package cn.v3;

/**
 * 多人聊天室 Version 3
 * Server服务器：找到CS多线程类
 *  读入放入线程中
 *  写出直接写在run方法
 *
 */
public class Server {
    private ServerSocket serverSocket;
    public Server(){
        try {
            serverSocket=new ServerSocket(0203);
        } catch(BindException e){
            System.out.println("端口号被占用，请检查");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void start() {
        Socket socket=null;
        String ip=null;
        try {
            while (true) {
                System.out.println("等待客户端连接");
                socket = serverSocket.accept();
                new Thread(new CS(socket)).start();
                ip=socket.getInetAddress().getHostAddress();
            }
        } catch (IOException e) {
            System.out.println(ip+"客户端链接断开链接~");
        } finally {

            if(serverSocket!=null&&serverSocket.isClosed()){
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    System.out.println("服务器关闭失败");
                }
                System.out.println("服务器关闭成功");
            }
        }
    }
    public static void main(String[] args){
        Server server=new Server();
        server.start();
    }
    //CS多线程类：控制客户端发来的通讯消息
    private class CS implements Runnable{
        private Socket socket;
        private String ip;
        public CS(Socket s){
            this.socket=s;
            ip=socket.getInetAddress().getHostAddress();
        }

        public void run(){
            PrintWriter pw=null;
            //BufferedReader br=null;
            try {
                //1.2  读入操作
                BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF8"));

                //1.1  写出操作【*】
                pw=new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),"UTF8")),true);
                //1.3  创建线程---lambda表达式--读入
                new Thread(()->{
                    //1.4   线程中--创建变量--接收客户端发来文本
                    try {
                        String message;
                        while((message= br.readLine())!=null){  //读入客户端
                            System.out.println("客户端说："+message);
                            //1.6  增加一句--每次客户端发给服务器端内容
                            System.out.print("服务器端请输入");
                        }
                    } catch (IOException e) {
                        System.out.println("客户端发来的消息断开了~~");
                    } finally {
                        if (br!=null)
                            try {
                                br.close();
                            } catch (IOException e) {
                                System.out.println("关闭读入流时出错"+e.getMessage());
                            }
                    }
                }).start();
                //1.5  增加写出操作【修改目的：读入写出通顺】
                //1.5.1  控制台卡住--输入内容
                Scanner input=new Scanner(System.in);
                //1.5.2  一直写出
                while(true){
                    System.out.println("服务器请输入：");
                    String sme=input.nextLine();
                    pw.println(ip+"服务器端说："+sme);
                }

            } catch(UnsupportedEncodingException e){
                System.out.println("请检查客户端/服务器端编码集：不一致！");
            } catch(SocketException e){
                System.out.println("客户端链接被重置");
            } catch(IOException e) {
                System.out.println("客户端链接失效了~");
            } finally {
                pw.close();
                if(socket!=null&&!socket.isClosed()){
                    System.out.println(ip+"客户端退出服务器链接~");
                    try {
                        socket.close();
                    } catch (IOException e) {
                        System.out.println(ip+"客户端退出链接异常~~");
                    }
                }
            }
        }
    }
}
